package org.lex.utils;

import java.util.Arrays;
import java.util.Comparator;

public class DefaultCategoryComparator<T extends Comparable<T>> implements CategoryComparator<T> {
	/**
	 * The comparator used to sort elements.
	 */
	private Comparator<T> comparator;

	/**
	 * Creates a new {@link DefaultCategoryComparator}
	 */
	public DefaultCategoryComparator() {
		this(null);
	}

	/**
	 * Creates a new {@link DefaultCategoryComparator}, which uses the given
	 * comparator
	 * 
	 * @param comparator
	 */
	public DefaultCategoryComparator(Comparator<T> comparator) {
		this.comparator = comparator;
	}

	/**
	 * Returns the comparator
	 * 
	 * @return the comparator
	 */
	protected Comparator<T> getComparator() {
		if (null == comparator) {
			comparator = new Comparator<T>() {
				public int compare(T o1, T o2) {
					return DefaultCategoryComparator.this.compare(o1, o2);
				}
			};
		}
		return comparator;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see lex.util.CategoryComparator#getCategory(T)
	 */
	public int getCategory(T element) {
		return 0;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see lex.util.CategoryComparator#compare(T, T)
	 */
	public int compare(T e1, T e2) {
		int cat1 = getCategory(e1);
		int cat2 = getCategory(e2);
		if (cat1 != cat2)
			return cat1 - cat2;
		return e1.compareTo(e2);
	}

	/**
	 * Sorts the given elements in-place, modifying the given array.
	 * <p>
	 * The default implementation of this method uses the java.util.Arrays#sort
	 * algorithm on the given array, calling <code>compare</code> to compare
	 * elements.
	 * </p>
	 * <p>
	 * Subclasses may reimplement this method to provide a more optimized
	 * implementation.
	 * </p>
	 * 
	 * @param elements
	 *            the elements to sort
	 */
	public void sort(T[] elements) {
		Arrays.sort(elements, getComparator());
	}
}
